﻿using System;
using System.Windows.Forms;
using BarberShop.Properties;

namespace BarberShop
{
    partial class MainForm
    {
        private void LoadDataFromDb()
        {
            Log.Info("Loading data from DB started");
            // TODO: This line of code loads data into the 'dbDataSet.Services' table. You can move, or remove it, as needed.
            servicesTableAdapter.Fill(dbDataSet.Services);
            // TODO: This line of code loads data into the 'dbDataSet.Clients' table. You can move, or remove it, as needed.
            clientsTableAdapter.Fill(dbDataSet.Clients);
            // TODO: This line of code loads data into the 'dbDataSet.Operations' table. You can move, or remove it, as needed.
            operationsTableAdapter.Fill(dbDataSet.Operations);
            Log.Info("Loading data from DB finished");
        }

        private void AddClient()
        {
            var adf = new AddClientForm();
            if (adf.ShowDialog() == DialogResult.OK)
            {
                dbDataSet.ClientsRow newRow = dbDataSet.Clients.NewClientsRow();

                newRow.Name = adf.ClientName;
                newRow.Surname = adf.ClientSurname;
                newRow.PrimaryPhone = adf.PrimaryPhone;
                newRow.SecondaryPhone = adf.SecondaryPhone;
                newRow.Note = adf.Notes;

                Log.Info("Adding new client " + newRow);

                dbDataSet.Clients.Rows.Add(newRow);

                UpdateClientsTable();

                Log.Info("New client added");
            }
        }

        public void AddService()
        {
            var adf = new AddServiceForm();
            if (adf.ShowDialog() == DialogResult.OK)
            {
                dbDataSet.ServicesRow newRow = dbDataSet.Services.NewServicesRow();

                newRow.Name = adf.ServiseName;
                newRow.Billable = adf.Billable.ToString().Substring(0, 1);

                Log.Info("Adding new service " + newRow);

                dbDataSet.Services.Rows.Add(newRow);

                UpdateServicesTable();

                Log.Info("New service added");
            }
        }

        private void AddOperation()
        {
            var adf = new AddOperatoinForm(dbDataSet.Services);
            if (adf.ShowDialog() == DialogResult.OK)
            {
                dbDataSet.OperationsRow newRow = dbDataSet.Operations.NewOperationsRow();

                newRow.ClientRef = GetSelectedClientId();
                newRow.ServiceRef = adf.ServiceId;
                newRow.Price = new decimal(adf.Price);
                newRow.Date = adf.Date;

                Log.Info("Adding new operation " + newRow);

                dbDataSet.Operations.AddOperationsRow(newRow);

                UpdateOperationsTable();
                UpdateOperationsPanel(GetSelectedClientId());

                Log.Info("New operation added");
            }
        }

        private void UpdateClientsTable()
        {
            ClearFilter();
            clientsBindingSource.EndEdit();
            clientsTableAdapter.Update(dbDataSet.Clients);
            clientsTableAdapter.Fill(dbDataSet.Clients);
            UpdateDbStatisticsLable();
        }

        private void UpdateServicesTable()
        {
            servicesBindingSource.EndEdit();
            servicesTableAdapter.Update(dbDataSet.Services);
            servicesTableAdapter.Fill(dbDataSet.Services);
            UpdateDbStatisticsLable();
        }

        private void UpdateOperationsTable()
        {
            operationsBindingSource.EndEdit();
            operationsTableAdapter.Update(dbDataSet.Operations);
            operationsTableAdapter.Fill(dbDataSet.Operations);
            UpdateDbStatisticsLable();
        }

        private void DeleteClient(int clientId)
        {
            dbDataSet.ClientsRow row = dbDataSet.Clients.FindByClientId(clientId);

            if (row == null)
            {
                Log.Warn("Trying to delete non existing client with id = " + clientId);
                return;
            }

            if (
                MessageBox.Show(String.Format(Resources.RealyWantToRemoveClient, row.Name),
                                Resources.ClientRemoveWarningMessage, MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                Log.Info("Deleting client " + row);

                DeleteClientOperations(clientId);

                row.Delete();
                UpdateClientsTable();

                Log.Info("Client with id = " + clientId + " deleted");
            }
        }

        public void DeleteService(int serviceId)
        {
            dbDataSet.ServicesRow row = dbDataSet.Services.FindByServiceId(serviceId);

            if (row == null)
            {
                Log.Warn("Trying to delete non existing service with id = " + serviceId);
                return;
            }

            if (MessageBox.Show(String.Format(Resources.RaealyWantToRemoveServiceAndAllConnectedOperations, row.Name),
                                Resources.ClientRemoveWarningMessage, MessageBoxButtons.OKCancel,
                                MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.OK)
            {
                Log.Info("Deleting service " + row);
                DeleteOperationsWithServiceRef(serviceId);

                row.Delete();
                UpdateServicesTable();
                Log.Info("Service with id = " + serviceId + " deleted");
            }
        }

        private void DeleteOperationsWithServiceRef(int serviceId)
        {
            var operationsWithServiceRef =
                (dbDataSet.OperationsRow[])
                dbDataSet.Operations.Select(dbDataSet.Operations.ServiceRefColumn.ColumnName + " = " + serviceId);
            var operationIds = new int[operationsWithServiceRef.Length];
            for (int i = 0; i < operationsWithServiceRef.Length; i++)
            {
                operationIds[i] = Convert.ToInt32(operationsWithServiceRef[i].OperationId);
            }

            foreach (int operationId in operationIds)
            {
                DeleteOperationWithConfirmation(operationId, false);
            }
        }

        private void DeleteClientOperations(int clientId)
        {
            var clientOperations =
                (dbDataSet.OperationsRow[])
                dbDataSet.Operations.Select(dbDataSet.Operations.ClientRefColumn.ColumnName + " = " + clientId);
            var operationIds = new int[clientOperations.Length];
            for (int i = 0; i < clientOperations.Length; i++)
            {
                operationIds[i] = Convert.ToInt32(clientOperations[i].OperationId);
            }

            foreach (int operationId in operationIds)
            {
                DeleteOperationWithConfirmation(operationId, false);
            }
        }

        private void DeleteOperation(int operationId)
        {
            DeleteOperationWithConfirmation(operationId, true);
        }

        private void DeleteOperationWithConfirmation(int operationId, bool askConfirmation)
        {
            dbDataSet.OperationsRow row = dbDataSet.Operations.FindByOperationId(operationId);

            if (row == null)
            {
                Log.Warn("Trying to delete non existing operation with id = " + operationId);
                return;
            }

            if (askConfirmation)
            {
                if (MessageBox.Show(String.Format(Resources.RealyWantToRemoveOperation,
                                                  row.Date), Resources.OperationRemoveWarningMessage,
                                    MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation,
                                    MessageBoxDefaultButton.Button2) ==
                    DialogResult.Cancel)

                    return;
            }

            Log.Info("Deleting operation " + row);

            row.Delete();
            UpdateOperationsTable();

            if (askConfirmation)
            {
                UpdateOperationsPanel(GetSelectedClientId());
            }

            Log.Info("Operation with id = " + operationId + " deleted");
        }
    }
}